﻿namespace LinFu.AOP.Interfaces
{
    using System;
    using System.Collections.Generic;

    public class CompositeAroundInvoke : IAroundInvoke
    {
        #region Fields

        private IList<IAroundInvoke> _aroundInvokeList = new List<IAroundInvoke>();

        #endregion Fields

        #region Constructors

        public CompositeAroundInvoke(IEnumerable<IAroundInvoke> aroundInvokeList)
        {
            if (aroundInvokeList == null)
                throw new ArgumentNullException("aroundInvokeList");

            // Filter out the null values
            foreach (var current in aroundInvokeList)
            {
                if (current == null)
                    continue;

                _aroundInvokeList.Add(current);
            }
        }

        #endregion Constructors

        #region Properties

        public IList<IAroundInvoke> AroundInvokeList
        {
            get { return _aroundInvokeList; }
        }

        #endregion Properties

        #region Methods

        public void AfterInvoke(IInvocationContext context, object returnValue)
        {
            foreach (var invoke in _aroundInvokeList)
            {
                invoke.AfterInvoke(context, returnValue);
            }
        }

        public void BeforeInvoke(IInvocationContext context)
        {
            IModifiableType obj = context.Target as IModifiableType;

            foreach (var invoke in _aroundInvokeList)
            {
                if (obj != null && obj.IsInterceptionDisabled)
                    return;

                invoke.BeforeInvoke(context);
            }
        }

        #endregion Methods
    }
}